﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Documents;
using System.IO;
using Table = FCNS.Data.Table;
using System.Windows.Data;
using DoubleH.Utility.Configuration;
using System.Diagnostics;
using FCNS.Data;

namespace DoubleH.Utility
{
    public class PrintFunction
    {
        static Configuration.PrintConfig config = null;
        static object corSId = null;
        public delegate bool PrintOrder(object order, DataTableText tableText);
        public static event PrintOrder BeginPrintOrder;

        static FormPrint printForm = null;
        /// <summary>
        /// 打印窗体
        /// </summary>
        public static FormPrint PrintForm
        {
            get { return printForm; }
        }

        /// <summary>
        /// 主程序运行时必须调用它
        /// </summary>
        public static void Init()
        {
            printForm = new FormPrint();
            printForm.Show();
        }
        /// <summary>
        /// 主程序关闭时必须调用它
        /// </summary>
        public static void Dispose()
        {
            if (printForm != null)
                printForm.Close();

            printForm = null;
        }

        private static void PrintNoWindow(string html)
        {
            Debug.Assert(printForm != null);

            printForm.AutoPrint = true;
            printForm.Init(corSId, config, html);
        }

        public static void PrintPosOrder(Table.PosOrderS order)
        {
           string[] html = DataToHtml(order, File.ReadAllText(GetTempleteFile("pos","pos/pos.html"), UTF8Encoding.UTF8));
            if (html != null&&html.Length>0)
                PrintNoWindow(html[0]);
        }

        public static void PrintPosJiaoBan(string user, string pos, string getMoney, string allMoney)
        {
            string file = DbDefine.printDir + "pos/posOver.html";
            if (!File.Exists(file))
            {
                MessageWindow.Show("打印模板丢失");
                return;
            }
            GetTempleteFile("posOver","pos/posOver.html");

            StringBuilder sb = new StringBuilder(File.ReadAllText(file, UTF8Encoding.UTF8));
            sb.Replace("[user]", user);
            sb.Replace("[pos]", pos);
            sb.Replace("[getMoney]", getMoney);
            sb.Replace("[allMoney]", allMoney);
            sb.Replace("[dateTime]", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));

            PrintNoWindow(sb.ToString());
        }

        /// <summary>
        /// 打印单据
        /// </summary>
        /// <param name="order"></param>
        /// <param name="tableText"></param>
        public static void Print(object order, DataTableText tableText)
        {
            if (order == null)
                return;

            Table.DataTableS dts = order as Table.DataTableS;
            if (dts == null)
                return;
            if (Table.SysConfig.SysConfigParams.PrintAfterSaveOrder && dts.Id == -1)
                return;

            if (BeginPrintOrder != null)
                if (!BeginPrintOrder(order, tableText))
                    return;

            string[] html = DataToHtml(order, ReadHtmlFile(order, tableText));
            if (html != null)
                ShowPrint(html);
        }

        /// <summary>
        /// 仅限非 DataTableText 的项目调用（例如：供插件使用）
        /// </summary>
        /// <param name="html">网页流</param>
        /// <param name="templeteFileString">打印的模板文件流</param>
        /// <param name="configFileFlag">配置文件标记，由于没有DataTableText，所以自定义一个名字用于存储打印参数。</param>
        public static void Print(object dt, string templeteFileString, string configFileFlag,bool taoDa)
        {
            if (dt == null || string.IsNullOrEmpty(templeteFileString))
                return;

            GetTempleteFile(configFileFlag);
            config.IsTaoDa = taoDa;
            string[] h = DataToHtml(dt, templeteFileString);
            if (h != null)
                ShowPrint(h);
        }

        /// <summary>
        /// 打印列表
        /// </summary>
        /// <param name="dataGridObject"></param>
        /// <param name="tableText"></param>
        public static void PrintList(DataGrid dataGridObject,object otherObj, MenuItemBinding menuItem, string defaultTempleteFile = null)
        {
            Debug.Assert(dataGridObject != null && menuItem != null);

            string file = GetTempleteFile(menuItem.TableText.ToString(), defaultTempleteFile);
            if (!ExistsFile(file))
                return;

            StringBuilder sb = new StringBuilder(File.ReadAllText(file,Encoding.GetEncoding("gb2312")));
            if (otherObj != null)
                ReplaceText(sb, otherObj);

            StringBuilder sb2 = new StringBuilder("<table class='detailClass' width='100%' border='0'><tr>");
            IEnumerable allColumns = menuItem.UserParams.Items.Where(f => f.Visible == true);
            foreach (DataGridColumnHeaderBinding header in allColumns)
                sb2.Append("<td class='detailTd" + header.Index + "'>" + header.Header + "</td>");

            sb2.Append("</tr>");
            //内容
            for (int i = 0; i < dataGridObject.Items.Count; i++)
            {
                var vr = dataGridObject.Items[i];
                Type ty = vr.GetType();
                sb2.Append("<tr>");
                foreach (DataGridColumnHeaderBinding header in allColumns)
                {
                    System.Reflection.PropertyInfo vt = ty.GetProperty(header.BindingName);
                    try
                    {
                        object obj = vt.GetValue(vr, null);
                        string f = (obj == null ? string.Empty : obj.ToString());
                        if (header.ColumnType == "Image")
                        {
                            if (File.Exists(f))
                                sb2.Append("<td class='detailTd_" + header.BindingName + "'><img src='" + f + "' /></td>");
                            else
                                sb2.Append("<td class='detailTd_" + header.BindingName + "'> </td>");
                        }
                        else
                            sb2.Append("<td class='detailTd_" + header.BindingName + "'>" + f + "</td>");
                    }
                    catch { sb2.Append("<td class='detailTd_" + header.BindingName + "'></td>"); }
                }
                sb2.Append("</tr>");
            }
            sb2.Append("</table>");
            sb.Replace("[objList]", sb2.ToString());

            ShowPrint(sb.ToString());
        }
        /// <summary>
        /// 将订单数据转换成html代码
        /// </summary>
        /// <param name="order"></param>
        /// <param name="tableText"></param>
        /// <returns></returns>
        public static string[] DataToHtml(object order, string templeteString)
        {
            StringBuilder sb = new StringBuilder(templeteString);
            if (sb.Length == 0)
                return null;

            config.Row = 0;
            AddCompanyInfo( sb);
            List<string> allHtml = new List<string>();
            string productListName = ReplaceText(sb, order);
            string okHtml = sb.ToString();
            if (string.IsNullOrEmpty(productListName))
                allHtml.Add(okHtml);
            else
            {
                Type ty = order.GetType();
                System.Reflection.PropertyInfo pi = ty.GetProperty(productListName);
                Debug.Assert(pi != null);

                //设置列表型的数据 [productSList] 为网页中的定点标记
                IList<Table.ProductS> ps = pi.GetValue(order, null) as IList<Table.ProductS>;
                if (config.Row == 0)
                {
                    sb.Replace("[productSList]", SetProductSList(ps));
                    allHtml.Add(sb.ToString());
                }
                else
                {
                    int psCount = ps.Count;
                    for (int i = 0; i < psCount; i += config.Row)
                    {
                        sb = new StringBuilder(okHtml);
                        List<Table.ProductS> tempPS = new List<Table.ProductS>();
                        for (int j = i; j < i + config.Row; j++)
                            if (j < psCount)
                                tempPS.Add(ps[j]);

                        sb.Replace("[productSList]", SetProductSList(tempPS));
                        //File.WriteAllText(@"c:\print.html", sb.ToString());
                        allHtml.Add(sb.ToString());
                    }
                }
            }
            return allHtml.ToArray();
        }
        /// <summary>
        /// 添加自己公司的信息
        /// </summary>
        private static void AddCompanyInfo( StringBuilder sb)
        {
            sb.Replace("[CompanyName]", Table.SysConfig.SysConfigParams.CompanyName);
            sb.Replace("[CompanyTel]", Table.SysConfig.SysConfigParams.CompanyTel);
            sb.Replace("[CompanyAddress]", Table.SysConfig.SysConfigParams.CompanyAddress);
        }

        private static string ReadHtmlFile(object order, DataTableText tableText)
        {
            string file = GetTempleteFile(tableText.ToString());
            if (!ExistsFile(file))
                return null;

            return File.ReadAllText(file, Encoding.GetEncoding("gb2312"));
        }

        private static bool ExistsFile(string fileName)
        {
            if (!File.Exists(fileName))
            {
                MessageWindow.Show(fileName + "打印格式丢失");
                PrintConfig cf = new PrintConfig();
                cf.Init(config);
                cf.ShowDialog();
                return false;
            }
            return true;
        }

        /// <summary>
        /// 替换网页 [] 标记的文本,只能替换固定的字段值
        /// </summary>
        /// <param name="sb"></param>
        /// <param name="order"></param>
        /// <returns>如果订单存在商品列表,返回商品列表的标识名,例如:ProductSList,ProductInRepairSList</returns>
        private static string ReplaceText(StringBuilder sb, object order)
        {
            //StringBuilder printScript = new StringBuilder("<script language=\"javascript\"  type=\"text/javascript\"  src=\"" +
            //    FCNS.Data.DbDefine.printDir + "js\\math.js\"></script>");
            //printScript.Append("<script type=\"text/javascript\"  src=\"" +
            //    FCNS.Data.DbDefine.printDir + "js\\print.js\"></script>");

            StringBuilder printScript = new StringBuilder("<script language=\"javascript\"  type=\"text/javascript\">" +
                File.ReadAllText(FCNS.Data.DbDefine.printDir + "js\\math.js") + "</script>");

            sb.Replace("<!--PrintScript-->", printScript.ToString());//用这个来加载js文件，如果是相对路径在网页中设置，是不能生效的，因为WebBrowser用的是Text方法

            Type ty = order.GetType();
            System.Reflection.PropertyInfo pi = ty.GetProperty("CorSId");
            if (pi != null)
                corSId = pi.GetValue(order, null);

            string productListName = null;
            foreach (System.Reflection.PropertyInfo info in ty.GetProperties())
            {
                object obj = info.GetValue(order, null) ?? "";
                sb.Replace("[" + info.Name + "]", obj.ToString());
                switch (info.Name)
                {
                    case "ProductSList":
                    case "ProductInRepairSList":
                    case "ProductInWeiBaoSList":
                        productListName = info.Name;
                        break;
                }
            }

            //sb.Replace("[CompanyName]", Table.SysConfig.SysConfigParams.CompanyName);
            //sb.Replace("[CompanyTel]", Table.SysConfig.SysConfigParams.CompanyTel);
            //sb.Replace("[CompanyAddress]", Table.SysConfig.SysConfigParams.CompanyAddress);

            return productListName;
        }

        private static string SetProductSList(IList<Table.ProductS> productS)
        {
            Type ty = typeof(Table.ProductS);
            StringBuilder sb = new StringBuilder("var productSList=new Array();");
            for (int i = 0; i < productS.Count; i++)
            {
                string key = "i" + i;
                sb.Append("var " + key + "=new Array();");
                Table.DataTableS ps = productS[i];
                foreach (System.Reflection.PropertyInfo info in ty.GetProperties())
                {
                    object obj = info.GetValue(ps, null) ?? "";
                    string str = obj.ToString();
                    if (str.EndsWith(@"\") && !str.EndsWith(@"\\"))
                        str += "\\";

                    sb.Append(key + "[\"" + info.Name + "\"]=\"" + str + "\";");
                }
                sb.Append("productSList[" + i + "]=" + key + ";");
            }
            if (config != null)
            {
                int count = productS.Count;
                while (count < config.Row)
                {
                    string key = "i" + count;
                    sb.Append("var " + key + "=new Array();");
                    sb.Append("productSList[" + count + "]=" + key + ";");
                    count += 1;
                }
            }
            return sb.ToString();
        }
        //private static string SetList(IList<Table.ProductSInRepairS> productS)
        //{
        //    Type ty = typeof(Table.ProductS);
        //    StringBuilder sb = new StringBuilder("var objList=new Array();");
        //    for (int i = 0; i < productS.Count; i++)
        //    {
        //        string key = "i" + i;
        //        sb.Append("var " + key + "=new Array();");
        //        Table.ProductSInRepairS ps = productS[i];
        //        foreach (System.Reflection.PropertyInfo info in ty.GetProperties())
        //        {
        //            if (ps.Id == -1)
        //                sb.Append(key + "[\"" + info.Name + "\"]=\"\";");
        //            else
        //            {
        //                object obj = info.GetValue(ps, null) ?? "";
        //                sb.Append(key + "[\"" + info.Name + "\"]=\"" + obj.ToString() + "\";");
        //            }
        //        }
        //        sb.Append("objList[" + i + "]=" + key + ";");
        //    }
        //    return sb.ToString();
        //}
        //private static string SetList(IList<Table.ProductSInWeiBaoS> productS)
        //{
        //    Type ty = typeof(Table.ProductS);
        //    StringBuilder sb = new StringBuilder("var objList=new Array();");
        //    for (int i = 0; i < productS.Count; i++)
        //    {
        //        string key = "i" + i;
        //        sb.Append("var " + key + "=new Array();");
        //        Table.ProductSInWeiBaoS ps = productS[i];
        //        foreach (System.Reflection.PropertyInfo info in ty.GetProperties())
        //        {
        //            if (ps.Id == -1)
        //                sb.Append(key + "[\"" + info.Name + "\"]=\"\";");
        //            else
        //            {
        //                object obj = info.GetValue(ps, null) ?? "";
        //                sb.Append(key + "[\"" + info.Name + "\"]=\"" + obj.ToString() + "\";");
        //            }
        //        }
        //        sb.Append("objList[" + i + "]=" + key + ";");
        //    }
        //    return sb.ToString();
        //}

        private static void ShowPrint(params string[] html)
        {
            ConfigSerializer.InitPrintMargin(config.Left, config.Top, config.Right, config.Bottom);
            printForm.Visible = true;
            printForm.Init(corSId, config, html);
        }

        private static string GetTempleteFile(string dataTableTextName, string defaultTempleteFile = null)
        {
            config = DoubleHConfig.AppConfig.PrintConfigItems.Find(f => f.TableText == dataTableTextName);
            if (config == null)
            {
                DoubleHConfig.AppConfig.PrintConfigItems.Add(config = new Configuration.PrintConfig() { TableText = dataTableTextName });
                if (string.IsNullOrEmpty(defaultTempleteFile))
                    config.FileName = "其它/List.html";
                else
                    config.FileName = defaultTempleteFile;
            }

            return DbDefine.printDir + config.FileName;
        }
    }
}